﻿using System.Collections.Generic;
using System.Linq;
using Nethereum.Generators.Net;
using Xunit;

namespace Nethereum.Generators.Tests
{
    public class TestStruct
    {
        [Fact]
        public void ShouldRetrieveStructTypeName()
        {
            var deserialiser = new StructABIDeserialiser();
            var dictionary = new Dictionary<string, object>();
            dictionary.Add("internalType", "struct Test.TestStruct");
            var structType = deserialiser.TryGetStructInternalType(dictionary);
            Assert.Equal("TestStruct", structType);
        }

        [Fact]
        public void ShouldRetrieveAllStructsFromABI()
        {
            var abi = @"[{""anonymous"":false,""inputs"":[{""indexed"":false,""internalType"":""address"",""name"":""sender"",""type"":""address""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct1"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct2"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""indexed"":false,""internalType"":""struct Test.TestStruct"",""name"":""testStruct"",""type"":""tuple""}],""name"":""TestStructStorageChanged"",""type"":""event""},{""inputs"":[],""name"":""GetTest"",""outputs"":[{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct1"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct2"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.TestStruct"",""name"":""testStruct"",""type"":""tuple""},{""internalType"":""int256"",""name"":""test1"",""type"":""int256""},{""internalType"":""int256"",""name"":""test2"",""type"":""int256""}],""stateMutability"":""pure"",""type"":""function""},{""inputs"":[{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct1"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct2"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.TestStruct"",""name"":""testStruct"",""type"":""tuple""}],""name"":""SetStorageStruct"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct1"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct2"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.TestStruct"",""name"":""testScrut"",""type"":""tuple""}],""name"":""Test"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},{""inputs"":[],""name"":""TestArray"",""outputs"":[{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""internalType"":""uint256"",""name"":""id2"",""type"":""uint256""}],""internalType"":""struct Test.SimpleStruct[2]"",""name"":""structArray"",""type"":""tuple[2]""}],""stateMutability"":""pure"",""type"":""function""},{""inputs"":[],""name"":""id1"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""id2"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""id3"",""outputs"":[{""internalType"":""uint256"",""name"":"""",""type"":""uint256""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""id4"",""outputs"":[{""internalType"":""string"",""name"":"""",""type"":""string""}],""stateMutability"":""view"",""type"":""function""},{""inputs"":[],""name"":""testStructStorage"",""outputs"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct1"",""type"":""tuple""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""},{""components"":[{""internalType"":""uint256"",""name"":""id"",""type"":""uint256""}],""internalType"":""struct Test.SubSubStruct"",""name"":""sub"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""internalType"":""struct Test.SubStruct"",""name"":""subStruct2"",""type"":""tuple""},{""internalType"":""string"",""name"":""id2"",""type"":""string""}],""stateMutability"":""view"",""type"":""function""}]";
            var deserialiser = new GeneratorModelABIDeserialiser();
            var contractAbi = deserialiser.DeserialiseABI(abi);
            Assert.Equal(4,contractAbi.Structs.Length);
            Assert.NotNull(contractAbi.Structs.FirstOrDefault(x => x.Name == "SubSubStruct"));
            Assert.NotNull(contractAbi.Structs.FirstOrDefault(x => x.Name == "SubStruct"));
            Assert.NotNull(contractAbi.Structs.FirstOrDefault(x => x.Name == "TestStruct"));
            Assert.NotNull(contractAbi.Structs.FirstOrDefault(x => x.Name == "SimpleStruct"));
        }
    }
}